#include <iostream>
#include <string>
#include <errno.h>
#include <cstring>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "Log.hpp"
#include "Thread.hpp"

void Usage(const char *str)
{
    std::cout << "\nUsage: " << str << " IP port\n"
              << std::endl;
}

struct SockData
{
    SockData(int sock, const struct sockaddr_in &sockaddr)
        : _sock(sock),
          _sockaddr(sockaddr)
    {
    }
    int _sock;
    struct sockaddr_in _sockaddr;
};

void *sendtoserver(void *args) // 发送信息
{
    SockData sockdata = *(SockData *)(((Thread_Data *)args)->args);
    int sock = sockdata._sock;
    struct sockaddr_in sockaddr = sockdata._sockaddr;

    std::string message;
    while (true)
    {
        std::cerr << "echo请输入:" << std::endl;
        std::getline(std::cin, message);
        if (message == "quit")
        {
            printf("成功退出\n");
            exit(0);
        }
        // 发送
        sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
    }
}

void *recvformserver(void *args) // 接收信息
{
    SockData sockdata = *(SockData *)(((Thread_Data *)args)->args);
    int sock = sockdata._sock;

    char buffer[1024];
    while (true)
    {
        // 接收
        ssize_t sz = recv(sock, buffer, sizeof buffer, 0);
        buffer[sz] = 0;
        if (sz > 0)
        {
            std::cout << buffer << std::endl;
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
    }
    // 创建套接字
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        Messagelog(FATAL, "%d-%s", errno, strerror(errno));
        exit(2);
    }
    // 套接字地址
    struct sockaddr_in sockaddr;
    memset(&sockaddr, 0, sizeof(sockaddr));
    sockaddr.sin_port = htons(atoi(argv[2]));
    sockaddr.sin_addr.s_addr = inet_addr(argv[1]);
    sockaddr.sin_family = AF_INET;
    socklen_t len = sizeof sockaddr;
    SockData sockdata(sock, sockaddr);

    Thread cli_send(1, sendtoserver, (void *)&sockdata); // 犯过第二sb的错误，名字写的太像了要写sockdata
    Thread cli_recv(2, recvformserver, (void *)&sockdata);

    cli_send.run();
    cli_recv.run();

    cli_recv.join();
    cli_send.join();

    // char buffer[1024];
    // std::string message;
    // while(true)
    // {
    //     std::cout << "echo请输入:" << std::endl;
    //     std::getline(std::cin, message);
    //     if(message == "quit") break;
    //     // 发送
    //     sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr*)&sockaddr, len);
    //     // 接收
    //     ssize_t sz = recv(sock, buffer, sizeof buffer, 0);
    //     buffer[sz] = 0;
    //     if(sz > 0)
    //     {
    //         std::cout << "server:\n"<< buffer << std::endl;
    //     }
    // }
    close(sock);

    return 0;
}
